package iotwisp.school.api.controller.pc_user;

import iotwisp.base.cqrs.BaseQO;
import iotwisp.base.cqrs.BusinessException;
import iotwisp.base.orm.query.pagination.Pagination;
import iotwisp.base.rest.JSONResultDTO;
import iotwisp.base.rest.RestBaseController;
import iotwisp.base.util.ValidationUtils;
import iotwisp.school.api.dto.AuthorityDTO;
import iotwisp.school.api.dto.AuthorityItemDTO;
import iotwisp.school.api.dto.MenuDTO;
import iotwisp.school.user.command.user.CreateUserSCmd;
import iotwisp.school.user.command.user.ModifyUserSCmd;
import iotwisp.school.user.command.user.UserLoginSCmd;
import iotwisp.school.user.command.user.UserRegisterSCmd;
import iotwisp.school.user.entity.ApiOperate;
import iotwisp.school.user.entity.LoginToken;
import iotwisp.school.user.entity.User;
import iotwisp.school.user.entity.UserPcMenu;
import iotwisp.school.user.qo.ApiOperateQO;
import iotwisp.school.user.qo.UserPcMenuQO;
import iotwisp.school.user.qo.UserQO;
import iotwisp.school.user.service.ApiOperateService;
import iotwisp.school.user.service.UserPcMenuService;
import iotwisp.school.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController("pcUserController")
@RequestMapping("/api/pc/user")
public class UserController extends RestBaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private UserPcMenuService userPcMenuService;
    @Autowired
    private ApiOperateService apiOperateService;

    @SuppressWarnings("unchecked")
    @PostMapping("/query")
    public ResponseEntity<JSONResultDTO> queryUser(@RequestBody UserQO qo) throws BusinessException {

        ValidationUtils.validate(qo);

        if (qo.getFetchRoles()) {
            qo.setBatchResult(true);
        }
        switch (qo.getResultType()) {
            case UserQO.RESULT_TYPE_COUNT:
                Integer count = userService.queryCount(qo);
                return ResponseEntity.ok(createSuccessResult(count));
            case UserQO.RESULT_TYPE_UNIQUE:
                User user = userService.queryUnique(qo);
                return ResponseEntity.ok(createSuccessResult(user));
            case UserQO.RESULT_TYPE_LIST:
                List<User> users = userService.queryList(qo);
                return ResponseEntity.ok(createSuccessResult(users));
            case UserQO.RESULT_TYPE_PAGINATION:
                Pagination pagination = userService.queryPagination(qo);
                return ResponseEntity.ok(createSuccessResult(pagination));
            default:
                return ResponseEntity.badRequest()
                        .body(createFailResult(BusinessException.NECESSARY_PARAM_NULL, "resultType值有误", null));
        }
    }

    @PostMapping("/register")
    public ResponseEntity<JSONResultDTO> register(@RequestBody UserRegisterSCmd cmd) throws BusinessException {

        User user = userService.register(cmd);
        return ResponseEntity.ok(createSuccessResult(user));
    }

    @PostMapping("/login")
    public ResponseEntity<JSONResultDTO> userLogin(@RequestBody UserLoginSCmd cmd) throws BusinessException {

        ValidationUtils.validate(cmd);

        LoginToken loginToken = userService.userLogin(cmd);
        return ResponseEntity.ok(createSuccessResult(loginToken));
    }

    @PostMapping("/create")
    public ResponseEntity<JSONResultDTO> create(@RequestBody CreateUserSCmd cmd) throws BusinessException {

        ValidationUtils.validate(cmd);

        User user = userService.createUser(cmd);
        return ResponseEntity.ok(createSuccessResult(user));
    }

    @PutMapping("/modify")
    public ResponseEntity<JSONResultDTO> modifyUser(@RequestBody ModifyUserSCmd cmd) throws BusinessException {
        ValidationUtils.validate(cmd);

        User user = userService.modifyUser(cmd);

        return ResponseEntity.ok(createSuccessResult(user));
    }


    @PostMapping("/authority/query")
    public ResponseEntity<JSONResultDTO> queryAuthority() {

        ApiOperateQO apiOperateQO = new ApiOperateQO();
        apiOperateQO.setResultType("list");
        apiOperateQO.setOrderByLeftValue(BaseQO.ORDER_ASC);
        List<ApiOperate> apiOperates = apiOperateService.queryList(apiOperateQO);

        List<AuthorityItemDTO> authorities = new ArrayList<>();
        for (int i = 1; i <= apiOperates.size(); i++) {
            AuthorityItemDTO authorityItemDTO = transApiOperate(apiOperates.get(i - 1));
            authorityItemDTO.setAuthority_id(i);
            authorities.add(authorityItemDTO);
        }
//        for (ApiOperate apiOperate : apiOperates) {
//            AuthorityItemDTO authorityItemDTO = transApiOperate(apiOperate);
//            authorities.add(authorityItemDTO);
//        }

        UserPcMenuQO userPcMenuQO = new UserPcMenuQO();
        userPcMenuQO.setResultType("list");
        userPcMenuQO.setOrderByLeftValue(BaseQO.ORDER_ASC);
        List<UserPcMenu> userPcMenus = userPcMenuService.queryList(userPcMenuQO);

        List<MenuDTO> menus = new ArrayList<>();
        for (int i = 1; i <= userPcMenus.size(); i++) {
            MenuDTO menuDTO = transUserMenu(userPcMenus.get(i - 1));
            menuDTO.setMenuId(i);
            menus.add(menuDTO);
        }
//        for (AdminMenu adminMenu : adminMenus) {
//            MenuDTO menuDTO = transAdminMenu(adminMenu);
//            menus.add(menuDTO);
//        }

        AuthorityDTO authorityDTO = new AuthorityDTO();
        authorityDTO.setMenus(menus);
        authorityDTO.setAuthorities(authorities);

        return ResponseEntity.ok(createSuccessResult(authorityDTO));
    }

    private AuthorityItemDTO transApiOperate(ApiOperate apiOperate) {

        AuthorityItemDTO authorityItemDTO = new AuthorityItemDTO();
//        authorityItemDTO.setAuthority_id(apiOperate.getId());
        authorityItemDTO.setAuthority_code(apiOperate.getId());
        authorityItemDTO.setAuthority_name(apiOperate.getName());
        return authorityItemDTO;
    }

    private MenuDTO transUserMenu(UserPcMenu menu) {
        MenuDTO menuDTO = new MenuDTO();
//        menuDTO.setMenuId(adminMenu.getId());
        menuDTO.setIcon(menu.getIcon());
        menuDTO.setLink(menu.getLink());
        menuDTO.setDepth(menu.getTreeData().getLevel());
        menuDTO.setRgt(menu.getTreeData().getRightValue());
        menuDTO.setLft(menu.getTreeData().getLeftValue());
        menuDTO.setMenuName(menu.getName());
        menuDTO.setMenuCode(menu.getCode());
        return menuDTO;
    }

}
